package edu.pitt.cs.cs2510.project3.algorithm;

import java.util.ArrayList;

import edu.pitt.cs.cs2510.project3.configuration.InputParameters;
import edu.pitt.cs.cs2510.project3.model.*;

//Manages deletion of files from a frontend.
public class Deleter {

	final float DeleteHotnessThreshold;
	final FrontEnd fe;
	final InputParameters simParams;
	
	public Deleter(InputParameters simulatorParameters, FrontEnd frontEnd) {
		fe = frontEnd;
		simParams = simulatorParameters;
		DeleteHotnessThreshold = (float) simulatorParameters.getDeleteHotness();
	}
	
	private ArrayList<Integer> deleteTrack = new ArrayList<Integer>();
	
	public void runAlgorithm() {	
		for(int i=0; i<fe.getWorkerCount(); i++) {
			WorkerServer w = fe.getWorker(i);
			Integer[] files = w.getFileIds();
			float hotn = 0;
			for(Integer fid : files) {
				File f = w.getFile(fid.intValue());
				File ffe = fe.files.get(fid.intValue());
				if(ffe.numBlocks < ffe.size)
					continue; //in-replication
				if((hotn = ffe.getHotness(fe.time, simParams.getHotnessInterval())) < DeleteHotnessThreshold 
					&& w.canDelete(f)){
					w.deleteFile(f);
					if(!deleteTrack.contains(f.fileId) && ffe.numBlocks <= f.numBlocks)
						deleteTrack.add(f.fileId);
					System.out.println("DEL: file " + f.fileId + " deleted from WS " + w.getId() + ", h="+hotn);
				}
			}
		}
		if(deleteTrack.size() > 0) {
			for(Integer fid : deleteTrack){
				deleteUpdate(fid);
			}
			deleteTrack.clear();
		}
	}
	
	public void deleteUpdate(int fileId) {
		int highBlock = -1;
		for(int i=0; i<fe.getWorkerCount(); i++) {
			WorkerServer w = fe.getWorker(i);
			Integer[] files = w.getFileIds();
			for(Integer fid2 : files) 
				if(fid2.intValue() == fileId)
					highBlock = Math.max(w.getFile(fileId).numBlocks, highBlock);
		}
		if(highBlock < 0)
			fe.files.remove(fileId);
		else
			fe.files.get(fileId).numBlocks = highBlock;		
	}
}
